home *** CD-ROM | disk | FTP | other *** search
/ Reverse Code Engineering RCE CD +sandman 2000 / ReverseCodeEngineeringRceCdsandman2000.iso / RCE / Tools / Win95 Secrets / SETUP.Z / WALKHEAP.C < prev    next >
Encoding:
C/C++ Source or Header  |  1995-07-19  |  7.5 KB  |  255 lines

  1. //==================================
  2. // WALKHEAP - Matt Pietrek 1995
  3. // FILE: WALKHEAP.C
  4. //==================================
  5.  
  6. #include <windows.h>
  7. #include <stdio.h>
  8. #include "heapw32.h"
  9.  
  10. // Prototypes
  11. HANDLE WalkHeap( HANDLE hHeap );
  12. void DisplayFreeBlock( PFREE_HEAP_ARENA_DEBUG pFreeArena );
  13. void DisplayInUseBlock( PHEAP_ARENA_DEBUG pArena );
  14. void DisplayHeapFlags( BYTE flags );
  15. void MakeSomeAllocationsAndDeletions( HANDLE hHeap );
  16.  
  17. int main(int argc, char * argv[])
  18. {
  19.     HANDLE heap, anotherHeap;
  20.  
  21.     if ( (GetVersion() & 0xC0000000) != 0xC0000000 )
  22.     {
  23.         printf("WALKHEAP will only work with Win95\n");
  24.         return 0;       
  25.     }
  26.     
  27.     if ( !GetSystemMetrics(SM_DEBUG) )
  28.     {
  29.         printf("WALKHEAP will only work with the debug version of Win95\n");
  30.         return 0;
  31.     }
  32.     
  33.     if ( argc == 2 )    // If user supplied an hHeap to walk, do it.
  34.     {
  35.         HANDLE hHeap;
  36.         
  37.         if ( 1 == sscanf( argv[1], "%x", &hHeap ) )
  38.         {
  39.             WalkHeap( hHeap );
  40.         }
  41.         else
  42.             printf( "Syntax: \"WALKHEAP <hHeap>\" or just \"WALKHEAP\"\n");
  43.  
  44.         return 0;
  45.     }
  46.  
  47.     // No command line was specified.  Do default action.
  48.  
  49.     heap = GetProcessHeap();
  50.  
  51.     // First, make the main heap look more interesting
  52.     MakeSomeAllocationsAndDeletions( heap );
  53.  
  54.     // Create another heap to show heap chaining.
  55.     anotherHeap = HeapCreate( HEAP_GENERATE_EXCEPTIONS | HEAP_NO_SERIALIZE,
  56.                               0x80000, 0x100000 );
  57.  
  58.     // Walk all the heaps in the process.  New heaps are put at the head
  59.     // of the list.
  60.     heap = anotherHeap;
  61.     while ( heap )
  62.         heap = WalkHeap( heap );
  63.  
  64.     return 0;
  65. }
  66.  
  67. #define WIDTH 40
  68.  
  69. // Returns HANDLE for next heap in process, or 0 on failure
  70. HANDLE WalkHeap( HANDLE hHeap )
  71. {
  72.     PHEAP_HEADER_DEBUG pHeapHeader = (PHEAP_HEADER_DEBUG)hHeap;
  73.     PHEAP_ARENA_DEBUG pArena;
  74.     PFREE_LIST_HEADER_DEBUG pFreeListHdr;
  75.     unsigned i;
  76.  
  77.     if (   IsBadReadPtr( pHeapHeader, sizeof(HEAP_HEADER_DEBUG))
  78.         || pHeapHeader->signature != 0x4948 )
  79.     {
  80.         printf("%08X is not a valid heap handle\n", hHeap);
  81.         return 0;
  82.     }
  83.     
  84.     printf("Heap at %08X\n", pHeapHeader);
  85.     
  86.     printf("%-*s%08X\n", WIDTH, "size:", pHeapHeader->dwSize);
  87.  
  88.     printf("%-*s%08X\n", WIDTH, "next block:", pHeapHeader->nextBlock);
  89.  
  90.     printf("Free lists:\n");
  91.     pFreeListHdr = pHeapHeader->freeListArray;
  92.     
  93.     for ( i=0; i < 4; i++ )
  94.     {
  95.         printf("  Head:%08X  size: %X\n",
  96.                 &pFreeListHdr->freeArena,
  97.                 pFreeListHdr->dwMaxBlockSize);
  98.         pFreeListHdr++;     // Advance to next free list header
  99.     }
  100.  
  101.     printf("%-*s%08X\n", WIDTH, "Next heap:", pHeapHeader->nextHeap);
  102.  
  103.     printf("%-*s%08X\n", WIDTH, "CritSection:", pHeapHeader->pCriticalSection);
  104.  
  105.     // CRITICAL_SECTION criticalSection;    // 0x7C
  106.  
  107.     printf("%-*s%08X\n", WIDTH, "Creating EIP:", pHeapHeader->creating_EIP);
  108.     printf("%-*s%08X\n", WIDTH, "checksum:", pHeapHeader->checksum);
  109.     printf("%-*s%04X\n", WIDTH, "Creating Thread:",
  110.             pHeapHeader->creating_thread_ordinal);
  111.     printf("%-*s%02X\n", WIDTH, "Flags:", pHeapHeader->flags);
  112.     DisplayHeapFlags( pHeapHeader->flags );
  113.     printf("%-*s%04X\n", WIDTH, "Signature:", (WORD)pHeapHeader->signature);
  114.  
  115.     // The first arena starts after the heap header.  (The "+1" is C ptr math)
  116.     pArena = (PHEAP_ARENA_DEBUG)(pHeapHeader+1);
  117.  
  118.     printf("\nHeap Blocks\n");
  119.     printf("Block     Stat  Size      Checksum  Thrd\n"
  120.            "--------  ----  --------  --------  ----\n");
  121.  
  122.     pFreeListHdr = pHeapHeader->freeListArray;
  123.     for ( i=0; i < 4; i++ )
  124.     {
  125.         DisplayFreeBlock( &pFreeListHdr->freeArena );
  126.         pFreeListHdr++;     // Point at next free list head
  127.     }
  128.  
  129.     printf("\n");
  130.     
  131.     while ( 1 )
  132.     {
  133.         DWORD blockSize = pArena->size & ~0xA0000003;
  134.  
  135.         if ( blockSize == 0 )
  136.             break;
  137.  
  138.         if (   (pArena->signature != 0x4842)        // 0x4842 = "BH" (in-use)
  139.             && (pArena->signature != 0x4846) )      // 0x4846 = "FH" (free)
  140.             break;
  141.  
  142.  
  143.         if ( pArena->size & 1 )
  144.             DisplayFreeBlock( (PFREE_HEAP_ARENA_DEBUG)pArena );
  145.         else
  146.             DisplayInUseBlock( pArena );
  147.  
  148.         // Advance to next block
  149.         pArena = (PHEAP_ARENA_DEBUG)((DWORD)pArena + blockSize);
  150.     }
  151.  
  152.     printf("\n\n");
  153.  
  154.     return pHeapHeader->nextHeap;
  155. }
  156.  
  157. void DisplayInUseBlock( PHEAP_ARENA_DEBUG pArena )
  158. {
  159.     printf("%08X  used  %08X  %08X  %04X  EIP: %08X  \n",
  160.             pArena,
  161.             pArena->size & ~0xA0000003,
  162.             pArena->b.checksum, 
  163.             pArena->threadID,
  164.             pArena->a.alloc_EIP);   
  165. }
  166.  
  167. void DisplayFreeBlock( PFREE_HEAP_ARENA_DEBUG pFreeArena )
  168. {
  169.     printf("%08X  free  %08X  %08X  %04X  prev:%08X  next:%08X\n",
  170.             pFreeArena,
  171.             pFreeArena->arena.size & ~0xA0000003,
  172.             pFreeArena->freeBlockChecksum,
  173.             pFreeArena->arena.threadID,
  174.             pFreeArena->arena.a.prev,
  175.             pFreeArena->arena.b.next);  
  176. }
  177.  
  178. void MakeSomeAllocationsAndDeletions( HANDLE hHeap )
  179. {
  180.     LPVOID ptrArray[20];
  181.  
  182.     ptrArray[0] = HeapAlloc( hHeap, 0, 0x4 );
  183.     ptrArray[1] = HeapAlloc( hHeap, 0, 0x8 );
  184.     ptrArray[2] = HeapAlloc( hHeap, 0, 0xC );
  185.     ptrArray[3] = HeapAlloc( hHeap, 0, 0x10 );
  186.     ptrArray[4] = HeapAlloc( hHeap, 0, 0x14 );
  187.  
  188.     ptrArray[5] = HeapAlloc( hHeap, 0, 0x24 );
  189.     ptrArray[6] = HeapAlloc( hHeap, 0, 0x28 );
  190.     ptrArray[7] = HeapAlloc( hHeap, 0, 0x2C );
  191.     ptrArray[8] = HeapAlloc( hHeap, 0, 0x30 );
  192.     ptrArray[9] = HeapAlloc( hHeap, 0, 0x34 );
  193.  
  194.     ptrArray[10] = HeapAlloc( hHeap, 0, 0xC4 );
  195.     ptrArray[11] = HeapAlloc( hHeap, 0, 0xC8 );
  196.     ptrArray[12] = HeapAlloc( hHeap, 0, 0xCC );
  197.     ptrArray[13] = HeapAlloc( hHeap, 0, 0xD0 );
  198.     ptrArray[14] = HeapAlloc( hHeap, 0, 0xD4 );
  199.  
  200.     ptrArray[15] = HeapAlloc( hHeap, 0, 0x224 );
  201.     ptrArray[16] = HeapAlloc( hHeap, 0, 0x228 );
  202.     ptrArray[17] = HeapAlloc( hHeap, 0, 0x22C );
  203.     ptrArray[18] = HeapAlloc( hHeap, 0, 0x230 );
  204.     ptrArray[19] = HeapAlloc( hHeap, 0, 0x234 );
  205.  
  206.     // Put some stuff into the < 0x20 free list
  207.     HeapFree( hHeap, 0, ptrArray[3] );
  208.     HeapFree( hHeap, 0, ptrArray[1] );
  209.  
  210.     // Put some stuff into the < 0x80 free list
  211.     HeapFree( hHeap, 0, ptrArray[8] );
  212.     HeapFree( hHeap, 0, ptrArray[6] );
  213.  
  214.     // Put some stuff into the < 0x200 free list
  215.     HeapFree( hHeap, 0, ptrArray[13] );
  216.     HeapFree( hHeap, 0, ptrArray[11] );
  217.  
  218.     // Put some stuff into the < 0xFFFFFFFF free list
  219.     HeapFree( hHeap, 0, ptrArray[18] );
  220.     HeapFree( hHeap, 0, ptrArray[16] );
  221.     
  222.     // allocate some really big blocks ( > 1MB )
  223.     HeapAlloc( hHeap, 0, 0x200000 );
  224.     HeapAlloc( hHeap, 0, 0x180000 );
  225. }
  226.  
  227. typedef struct
  228. {
  229.     BYTE    flag;
  230.     PSTR    name;
  231. } BYTE_FLAG_DESCRIPTIONS;
  232.  
  233. BYTE_FLAG_DESCRIPTIONS HeapFlags[] = 
  234. {
  235. { 0x00000001, "HEAP_NO_SERIALIZE" },
  236. { 0x00000002, "HEAP_GROWABLE" },
  237. { 0x00000004, "HEAP_GENERATE_EXCEPTIONS" },
  238. { 0x00000008, "HEAP_ZERO_MEMORY" },
  239. { 0x00000010, "HEAP_REALLOC_IN_PLACE_ONLY" },
  240. { 0x00000020, "HEAP_TAIL_CHECKING_ENABLED" },
  241. { 0x00000040, "HEAP_FREE_CHECKING_ENABLED" },
  242. { 0x00000080, "HEAP_DISABLE_COALESCE_ON_FREE" }
  243. };
  244. #define HEAP_FLAGS_COUNT ( sizeof(HeapFlags) / sizeof(HeapFlags[0]) )
  245.  
  246. void DisplayHeapFlags( BYTE flags )
  247. {
  248.     unsigned i;
  249.     
  250.     for ( i=0; i < HEAP_FLAGS_COUNT; i++ )
  251.         if ( HeapFlags[i].flag & flags )
  252.             printf("%-*s%s\n", WIDTH, "", HeapFlags[i].name);
  253. }
  254.  
  255.